package demo10;


// 懒汉模式: 线程不安全---->加锁处理
// 指令重排序问题
class SingletonLazy {
    private static volatile SingletonLazy instance = null;

    public static SingletonLazy getInstance() {
        if (instance == null) {
            synchronized (SingletonLazy.class) {
                    instance = new SingletonLazy();
            }
        }
        // 此时这样加锁是不安全的，当我们调用这个方法的时，可能存在多线程都进入了if的判断，就可能导致new了多个实例

        synchronized (SingletonLazy.class) {
            if (instance == null) {
                instance = new SingletonLazy();
            }
        }
        //当我们进行上述加锁时，我们就将整个操作变成原子的了，此时线程安全，但是，如果后面每次调用这个方法时候都要加锁（开销大）

        if (instance == null) {
            synchronized (SingletonLazy.class) {
                if (instance == null) {
                    instance = new SingletonLazy();
                }
            }
        }
        // 最终代码： 当然这里加锁之后还有一个小问题，
        // 虽然整个操作变成原子的了，但是还是可能由于指令重排序的问题导致出现bug
        // 就比如： 创建一个新的对象时候---》 首先申请一块内存 ---》 初始化instance ，将内存地址给instance引用 ，
        // 那么后面这两个步骤就可能 由于随机调度出现顺序差别，就可能出现bug
        // 所以我们在对instance定义的时候需要加上 volatile 修饰
        return instance;
    }

    private SingletonLazy() { }
}
public class Test22 {
    public static void main(String[] args) {
        SingletonLazy s1=SingletonLazy.getInstance();
        SingletonLazy s2=SingletonLazy.getInstance();
        System.out.println(s1==s2);
    }
}
